import { Request, Response, NextFunction } from 'express'
import {
  getPosts,
  createPost,
  updatePost,
  deletePost,
  createPostTag,
  postHasTag,
  deletePostTag,
  getPostsTotalCount,
  getPostById
} from './post.service'
import _ from 'lodash'
import { TagModel } from '../tag/tag.model'
import { getTagByName, createTag } from '../tag/tag.service'

export const index = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const totalCount = await getPostsTotalCount({ filter: req.filterParmas })

    res.header('X-Total-Count', totalCount)

    const data = await getPosts({
      sort: req.sort,
      filter: req.filterParmas,
      pagination: req.pagination
    })
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const store = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { title, content } = req.body
  const { id: user_id } = req.user

  try {
    const data = await createPost({ user_id, title, content })
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const update = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const id = +req.params.postId
  const post = _.pick(req.body, ['title', 'content'])

  try {
    const data = await updatePost(id, post)
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const destory = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const id = +req.params.postId
  try {
    const data = await deletePost(id)
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const storePostTag = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { postId } = req.params
  const { name } = req.body

  let tag: TagModel

  try {
    tag = await getTagByName(name)
  } catch (error) {
    return next(error)
  }

  if (tag) {
    try {
      const postTag = await postHasTag(+postId, tag.id)
      if (postTag) throw new Error('TAG_ALREADY_EXISTS')
    } catch (error) {
      return next(error)
    }
  } else {
    try {
      const data = (await createTag({ name })) as any
      tag = { id: data.insertId }
    } catch (error) {
      return next(error)
    }
  }

  try {
    const data = await createPostTag(+postId, tag.id)
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const destoryPostTag = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { postId } = req.params
  const { tagId } = req.body

  try {
    const data = await deletePostTag(+postId, +tagId)
    res.send(data)
  } catch (error) {
    next(error)
  }
}

export const show = async (req: Request, res: Response, next: NextFunction) => {
  const { postId } = req.params
  try {
    const post = await getPostById(+postId)
    res.send(post)
  } catch (error) {
    next(error)
  }
}
